import asyncio
import json
import sys

import pandas as pd
import pygame
from pygame import MOUSEBUTTONDOWN, QUIT, KEYDOWN

import utils.utils
from domain.base import *
from scenes.base_scene import Scene
from scenes.office.clickable_image import ClickableImage
from scenes.office.colleague_list import ColleagueList
from scenes.office.dialog_box import DialogBox
from scenes.office.people import People
from scenes.office.project_dialog import ProjectDialog
from scenes.office.status_bar import StatusBar
from shared_variables import CONFIG, WHITE


class OfficeScene(Scene):

    def __init__(self, screen: pygame.surface.Surface, level_data: LevelData):
        super().__init__()

        self.screen = screen
        self.level_data = level_data

        background = pygame.image.load(CONFIG['assets']['office']['background'])
        self.background = pygame.transform.scale(background, (CONFIG['screen']['width'], CONFIG['screen']['height']))
        self.rect = self.background.get_rect()
        plan = pygame.image.load(CONFIG['assets']['office']['plan'])
        self.plan_image = ClickableImage(self.screen, plan, (850, 270))
        self.project_dialog = ProjectDialog(self.screen, (CONFIG['screen']['width'], CONFIG['screen']['height']),
                                            self.is_show_project_callback)
        self.dialog_box = DialogBox((100, 100), (400, 300), self.receive_from_keyboard)  # 创建一个DialogBox对象
        self.colleague_list: ColleagueList = None
        self.status_bar = None
        self.people = People(self.screen, (240, 100), CONFIG['assets']['office']['temp_potrait'])

        self.is_talking = False
        self.is_show_project = False
        self.loop = asyncio.get_event_loop()
        self.describe_task: asyncio.Task = None
        self.talk_task: asyncio.Task = None
        self.is_refresh = False
        self.is_first_dict = {}
        self.generate_image_once = True
        self.image_path = ''

    def load_assets(self):
        me_info = self.level_data.get_me_info()
        rename = {'cash': "现金", "salary": "薪水", "energy": '体力'}
        basic = me_info[["cash", "salary", "energy"]].rename(columns=rename).iloc[0].to_dict()
        self.status_bar = StatusBar(self.screen, (10, 10), basic)
        self.update_colleague_list()
        # 创建一个任务并运行协程
        # self.describe_task = asyncio.ensure_future(self.start_project_describe())
        self.is_talking = True

    def update(self):
        # pass
        # if not self.describe_task.done():
        #     self.loop.run_until_complete(asyncio.wait([self.describe_task], timeout=0))
        if self.talk_task is not None:
            if not self.talk_task.done():
                self.loop.run_until_complete(asyncio.wait([self.talk_task], timeout=0))

    def update_colleague_list(self):
        temp = self.level_data.get_people_role()
        temp = temp[~temp['role'].isin(['me', 'boss'])]
        self.colleague_list = ColleagueList(self.screen, (10, 180), temp)
        # todo 这个刷新可能会有问题
        self.is_refresh = True

    async def start_project_describe(self):
        data = self.level_data.prepare_data()

        print(f"老板是谁: {data['boss_name']}")
        self.level_data.set_talk_role(data['boss_name'])
        response = project_describe_version3(data['boss_name'], data['my_name'], data['project_name'], data['my_task'])

        self.level_data.update_one_talk('boss', data['boss_name'], response)
        self.people.update_potrait(data['boss_name'])
        self.people.update_talks(self.level_data.talks.get(data['boss_name']))
        self.dialog_box.dialog_up(data['boss_name'])

    def create_task(self, coro):
        """
        取消当前任务（如果存在）并创建一个新的 asyncio 任务
        """
        task = getattr(self, 'talk_task', None)
        if task and not task.done():
            task.cancel()
        self.talk_task = asyncio.ensure_future(coro)

    def receive_from_keyboard(self, content):
        # 存储对话
        me = self.level_data.get_me_info()
        self.level_data.update_one_talk('me', me['name'].values[0], content)

        # 更新people文字内容
        talking_to = self.level_data.talk_role
        self.people.update_potrait(talking_to)
        self.people.update_talks(self.level_data.talks.get(talking_to))

        # 判断路由g
        boss = self.level_data.get_boss()
        boss_name = boss['name'].values[0]
        LOGGER.info(f"boss: {boss_name} 还有 聊天对象是谁：{talking_to}")
        if talking_to == boss_name:
            # 创建并运行新的 talk_task
            self.create_task(self.talk_to_boss())
        else:
            # 创建并运行新的 talk_task
            self.create_task(self.talk_to_colleague(talking_to))
            print(f"talk task 是否是不能重新被赋值？ {self.talk_task} {self.talk_task.done()}")

    async def talk_to_boss(self):
        LOGGER.info(f"进入talk to boss 了")
        data = self.level_data.prepare_data()
        talks = self.level_data.talks.get(data['boss_name'])
        dialogs = '\n'.join([f"{dialog['name']}: {dialog['content']}" for dialog in talks])

        if not self.is_first_dict.get(data['boss_name'], True):
            relationship_update = await asyncio.to_thread(relationship_change, data['boss_name'], data['my_name'],
                                                          data['relationship'], dialogs)
            if relationship_update['is_change_relationship'] != 'unknown':
                data['relationship'] = relationship_update['new_relationship']
                self.level_data.update_relationship(data['boss_name'], data['my_name'],
                                                    relationship_update['new_relationship'])

        # 解析用户意图
        intent = await asyncio.to_thread(boss_get_intent, dialogs)

        # 根据意图执行不同逻辑
        if intent['intent'] == '接受':
            response = await asyncio.to_thread(format_response, data['boss_name'], "你接收我的安排，我很高兴，但是不要让我失望。",
                                               dialogs)
        elif intent['intent'] == '拒绝':
            response = await asyncio.to_thread(format_response, data['boss_name'],
                                               "失望，作为员工你是不合格的，你或者可以去找其他同事求助，求求我也是一个办法。",
                                               dialogs)
        elif intent['intent'] == 'unknown' or intent['intent'] == '其他':
            response = await asyncio.to_thread(normal_response, data['my_name'], dialogs)
        elif intent['intent'] == '要其他任务':
            job_name = get_task_name(dialogs)['task_name']

            if job_name == 'unknown':
                response = await asyncio.to_thread(normal_response, data['my_name'], dialogs)
            else:
                job_agree = await asyncio.to_thread(boss_ask_job_agree, data['boss_name'], data['my_name'],
                                                    data['relationship'], job_name,
                                                    dialogs)
                if job_agree['intent'] == '接受':
                    response = await asyncio.to_thread(boss_response, job_agree['reason'], job_agree['intent'],
                                                       job_name, data['my_name'],
                                                       data['boss_name'], dialogs)
                    print(self.level_data.data['taskPeopleLinks'])
                    self.level_data.reassign_task(job_name, data['my_name'])
                    print(self.level_data.data['taskPeopleLinks'])
                    # 打印reassign_task之前和之后的数据
                elif job_agree['intent'] == '拒绝':
                    response = await asyncio.to_thread(format_response, data['boss_name'], "想随便挑任务，不可能。",
                                                       dialogs)
                else:
                    response = await asyncio.to_thread(normal_response, data['my_name'], dialogs)
        else:
            response = await asyncio.to_thread(normal_response, data['my_name'], dialogs)

        self.level_data.update_one_talk('boss', data['boss_name'], response)
        self.people.update_potrait(data['boss_name'])
        self.people.update_talks(self.level_data.talks.get(data['boss_name']))
        self.is_first_dict[data['boss_name']] = False
        if self.level_data.talk_role == data['boss_name']:
            self.dialog_box.dialog_up(data['boss_name'])

    async def talk_to_colleague(self, colleague_name):
        print("進入了talk_to_colleague了麽")
        data = self.level_data.prepare_data(colleague_name)
        talks = self.level_data.talks.get(data['colleague_name'])
        # dialogs = '\n'.join([f"{dialog['name']}: {dialog['content']}" for dialog in talks])
        dialogs = talks[-1]['content']

        relationship_update = await asyncio.to_thread(relationship_change, data['colleague_name'], data['my_name'],
                                                      data['relationship'],
                                                      dialogs)
        # 更新关系，如果有变化
        if not self.is_first_dict.get(data['colleague_name'], True):
            if relationship_update['is_change_relationship'] != 'unknown':
                data['relationship'] = relationship_update['new_relationship']
                self.level_data.update_relationship(data['colleague_name'], data['my_name'],
                                                    relationship_update['new_relationship'])
                print(f"新的关系：{relationship_update['new_relationship']}")
                self.update_colleague_list()
        intent = await asyncio.to_thread(colleague_get_intent, data['my_name'], data['colleague_name'], dialogs)

        if intent['intent'] == '要你的任务':
            task_name = get_task_name(dialogs)['task_name']
            current_financial_status, future_financial_status = self.level_data.predict_finance(data)
            agree_result = await asyncio.to_thread(colleague_ask_job_is_agree,data['colleague_name'], data['my_name'], data['relationship'],
                                                      task_name, current_financial_status, future_financial_status)
            if agree_result['intent'] == '接受':
                response = await asyncio.to_thread(colleague_response, agree_result['reason'], task_name, "愿意",
                                                   data['my_name'],
                                                   data['colleague_name'], dialogs)
                self.level_data.reassign_task(task_name, data['my_name'])
                # 打印reassign_task之前和之后的数据
            else:
                response = await asyncio.to_thread(colleague_response, agree_result['reason'], task_name, "拒绝",
                                                   data['my_name'],
                                                   data['colleague_name'], dialogs)
        elif intent['intent'] == '给你任务':
            task_name = get_task_name(dialogs)['task_name']
            agree_result = await asyncio.to_thread(colleague_give_job_agree, data['my_name'], data['colleague_name'],
                                                   data['relationship'],
                                                   task_name)
            if agree_result['intent'] == '接受':
                response = await asyncio.to_thread(colleague_response, agree_result['reason'], task_name, "愿意",
                                                   data['my_name'],
                                                   data['colleague_name'], dialogs)
                self.level_data.reassign_task(task_name, data['colleague_name'])
                # 打印reassign_task之前和之后的数据
            else:
                response = await asyncio.to_thread(colleague_response, agree_result['reason'], task_name, "拒绝",
                                                   data['my_name'],
                                                   data['colleague_name'], dialogs)
        else:
            response = await asyncio.to_thread(normal_response, data['colleague_name'], dialogs)

        self.is_first_dict[data['colleague_name']] = False
        self.level_data.update_one_talk('colleague', colleague_name, response)
        self.people.update_potrait(colleague_name)
        self.people.update_talks(self.level_data.talks.get(colleague_name))
        if self.level_data.talk_role == data['colleague_name']:
            self.dialog_box.dialog_up(colleague_name)

    def is_show_project_callback(self):
        self.is_show_project = False

    def handle_events(self, event):
        # 处理事件
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            self.colleague_list.update(mouse_pos)
            if self.colleague_list.get_selected_colleague() is not None:
                selected_colleague = self.colleague_list.get_selected_colleague()
                self.is_talking = True
                print(f"点击了同事: {selected_colleague['name']}")
                self.level_data.set_talk_role(selected_colleague['name'])
                self.people.update_potrait(selected_colleague['name'])
                self.people.update_talks(self.level_data.talks.get(selected_colleague['name'], []))
                self.is_refresh = True
                self.dialog_box.dialog_up(selected_colleague['name'])

            self.plan_image.update(mouse_pos)
            if self.plan_image.is_clicked():
                # 绘制项目对话框
                print("点击了可点击图片")
                self.is_show_project = True
                self.generate_image_once = True

            if self.is_talking:
                self.people.handle_event(event, self.update_is_talking)

            if self.is_show_project:
                print("点击了 is_show_project")
                return self.project_dialog.handle_event(mouse_pos)

    def update_is_talking(self):
        self.is_talking = False

    def draw(self):
        # 绘制人物图像
        if self.is_refresh:
            self.screen.fill(WHITE)
            self.is_refresh = False
        # 绘制游戏界面
        self.screen.blit(self.background, self.rect)

        # 示例：绘制状态栏
        self.status_bar.draw()

        # 示例：绘制同事列表
        self.colleague_list.draw()

        self.plan_image.draw()

        if self.is_talking:
            self.people.draw()
            self.dialog_box.draw()

        if self.is_show_project:
            if self.generate_image_once:
                self.image_path = utils.utils.generate_group_graph(self.level_data.get_task_people())
                self.generate_image_once = False
            self.project_dialog.draw(self.image_path)

        pygame.display.flip()
